﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;

namespace Project.Library
{

    public class BlobStorage : IFile
    {
        private CloudStorageAccount storageAccount;
        public int Init(String ConnectionString)
        {
            try
            {
                storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(ConnectionString));
            }
            catch(Exception e)
            {
                throw e;
            }
            return 1;
        }

        public String Read(String BlobName)
        {
            try
            {
                // Create the table client.
                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

                // Create the table if it doesn't exist.
                CloudBlobContainer container = blobClient.GetContainerReference(GetContainerName(BlobName));

                // Retrieve reference to a blob 
                CloudBlockBlob blockBlob = container.GetBlockBlobReference(GetBlobName(BlobName));

                // Read Blob Return UTF8 String
                String retval = "";
                using (var memoryStream = new MemoryStream())
                {
                    blockBlob.DownloadToStream(memoryStream);
                    retval = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
                }

                return retval;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public int Write(String BlobName, String Data)
        {
            try
            {
                // Create the table client.
                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

                // Create the table if it doesn't exist.
                CloudBlobContainer container = blobClient.GetContainerReference(GetContainerName(BlobName));

                // Retrieve reference to a blob 
                CloudBlockBlob blockBlob = container.GetBlockBlobReference(GetBlobName(BlobName));
                if (container.Exists() == false)
                    return 2;

                // Write Stream To Blob
                using (var stream = new MemoryStream())
                {
                    using (StreamWriter oStreamWriter = new StreamWriter(stream))
                    {
                        oStreamWriter.Write(Data);
                        oStreamWriter.Flush();
                        stream.Position = 0;
                        blockBlob.UploadFromStream(stream);
                    }
                }

                return 1;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public int Write(String BlobName, Stream stream)
        {
            try
            {
                // Create the table client.
                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

                // Create the table if it doesn't exist.
                CloudBlobContainer container = blobClient.GetContainerReference(GetContainerName(BlobName));
                if (container.Exists() == false)
                    return 2;

                // Retrieve reference to a blob 
                CloudBlockBlob blockBlob = container.GetBlockBlobReference(GetBlobName(BlobName));

                // Write Stream To Blob
                blockBlob.UploadFromStream(stream);

                return 1;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public int Delete(String BlobName)
        {
            try
            {
                // Create the table client.
                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

                // Create the table if it doesn't exist.
                CloudBlobContainer container = blobClient.GetContainerReference(GetContainerName(BlobName));
             
                // Retrieve reference to a blob 
                CloudBlockBlob blockBlob = container.GetBlockBlobReference(GetBlobName(BlobName));
                
                // Delete the blob.
                blockBlob.Delete();
                return 1;
            }
            catch (Exception e)
            {
                throw e;
            }

        }

        public bool Exists(String BlobName)
        {
            try
            {
                // Create the table client.
                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

                // Create the table if it doesn't exist.
                CloudBlobContainer container = blobClient.GetContainerReference(GetContainerName(BlobName));

                // Retrieve reference to a blob 
                CloudBlockBlob blockBlob = container.GetBlockBlobReference(GetBlobName(BlobName));

                // Delete the blob.
                if (blockBlob.Exists())
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public int CreateFolder(String FolderName)
        {
            try
            {
                // Create the table client.
                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

                // Create the table if it doesn't exist.
                CloudBlobContainer container = blobClient.GetContainerReference(FolderName);
                if (container.Exists())
                {
                    container.SetPermissions(
                        new BlobContainerPermissions
                        {
                            PublicAccess =
                                BlobContainerPublicAccessType.Blob
                        });
                    return 2;
                }
                else
                {

                    container.CreateIfNotExists();
                    container.SetPermissions(
                        new BlobContainerPermissions
                        {
                            PublicAccess =
                                BlobContainerPublicAccessType.Blob
                        });
                    return 1;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public int DeleteFolder(String FolderName)
        {
            try
            {
                // Create the table client.
                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

                // Create the table if it doesn't exist.
                CloudBlobContainer container = blobClient.GetContainerReference(FolderName);
                if (container.Exists())
                {
                    container.DeleteIfExists();
                    return 1;
                }
                else
                {
                    return 2;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public bool ExistsFolder(String FolderName)
        {
            try
            {
                // Create the table client.
                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

                // Create the table if it doesn't exist.
                CloudBlobContainer container = blobClient.GetContainerReference(FolderName);
                if (container.Exists())
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        private String GetContainerName(String BlobName)
        {
            if (BlobName.Split('\\')[0].Contains(":") || BlobName.Split('\\')[0] == null || BlobName.Split('\\')[0] == "")
            {
                return BlobName.Split('\\')[1];
            }
            else
            {
                return BlobName.Split('\\')[0];
            }
        }

        private String GetBlobName(String BlobName)
        {

            int index1 = BlobName.IndexOf('\\');
            int index2 = BlobName.IndexOf("\\", index1 + 1);
            if (BlobName.Split('\\')[0].Contains(":") || BlobName.Split('\\')[0] == null || BlobName.Split('\\')[0] == "")
            {
                return BlobName.Substring(index2 + 1, (BlobName.Length - index2) - 1).Replace("\\", "//").Replace("//", "/");
            }
            else
            {
                return BlobName.Substring(index1 + 1, (BlobName.Length - index1) - 1).Replace("\\","//").Replace("//","/");
            }
        }
    }
}
